package util;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class ChecksumHelper {
	
	public static String AlgorithmType = "SHA1";

	public static String GetChecksum(String text) {
		InputStream stream = new ByteArrayInputStream(text.getBytes());
		
		return ChecksumHelper.GetChecksum(stream);
	}

	public static String GetChecksum(File file) {
		String output = "";
		
		if (file.isDirectory()) {
			 output = ChecksumHelper.GetDirectoryChecksum(file);
		 } else {
			 FileInputStream fis = null;
				try {
					fis = new FileInputStream(file);
				} catch (FileNotFoundException e) { e.printStackTrace(); }
			 output = ChecksumHelper.GetChecksum(fis);
		 }
		
		return output;
	}

	public static String GetFileChecksum(String fileName) {
		return ChecksumHelper.GetChecksum(new File(fileName));
	}

	public static String GetDirectoryChecksum(File file) {
		String output = "";
   	 
    	if (file.isDirectory()) {
	    	for (File f : file.listFiles()) {
	    		if (!f.isHidden())
	    			output += ChecksumHelper.GetChecksum(f);
			}
    	}
		
		return output;
	}
	
	public static String GetChecksum(InputStream stream) {
		
		// TODO: determine if we need to keep these in the checksum calculation
//		StringBuffer FileAttr = new StringBuffer("");
//	 	 FileAttr.append(file.getName());
//	 	 FileAttr.append(file.canRead());
//	 	 FileAttr.append(file.canWrite());
//	 	 FileAttr.append(file.canExecute());
//	 	 FileAttr.append(file.isHidden());
//	 	 FileAttr.append(file.lastModified());
//		 md.update(FileAttr.toString().getBytes()); //update the file attributes info
		
		MessageDigest md = null;
		try {
			md = MessageDigest.getInstance(ChecksumHelper.AlgorithmType);
		} catch (NoSuchAlgorithmException ex) {} // swallow it...
		
		
		 int nread = 0; 
		 byte[] dataBytes = new byte[1024];

		 try {
			while ((nread = stream.read(dataBytes)) != -1) {
				 md.update(dataBytes, 0, nread);
			 }
		} catch (IOException e) { e.printStackTrace(); }; // swallow all errors... is this good?
		 
		 byte[] mdbytes = md.digest();

		 //convert the byte to hex format
		 StringBuffer sb = new StringBuffer("");
		 
		 for (int i = 0; i < mdbytes.length; i++) {
			 sb.append(Integer.toString((mdbytes[i] & 0xff) + 0x100, 16).substring(1));
		 }
		 
		 return sb.toString();
	}
	
}